package be.destin.adp;

/*
 * Regex Token for validated assembly
 */
public class Rex {
	boolean atom; // if a suffix like "*" is put after the expression, the WHOLE expression is repeated or not?
	String expression;
	
	public Rex (char c) {
		atom = true;
		expression = encode(c);
	}
	
	public Rex (String s) {
		atom = s.length() > 1;
		StringBuffer sb = new StringBuffer();
		for (char c : s.toCharArray()) {
			sb.append(encode(c));
		}
		expression = sb.toString();
	}
	
	public Rex (String s, boolean atom) {
		this.atom = atom;
		this.expression = s;
	}
	
	public Rex add(Rex toAdd) {
		return new Rex(this.getExpression()+toAdd.getExpression(),false);
	}

	public Rex add(String toAdd) {
		String result = this.getExpression();
		for (char c : toAdd.toCharArray()) {
			result += encode(c);
		}
		return new Rex(result,false);
	}

	public Rex add(char toAdd) {
		return new Rex(this.getExpression()+encode(toAdd),false);
	}

	public String getExpression() {
		return this.expression;
	}
	public String toString() {
		return this.expression; // Atomic node management is not desired in this case...
	}	
	
	public static String getExpression(Rex... p) {
		StringBuffer sb = new StringBuffer();
		for (int i = 0; i < p.length; i++) {
			sb.append(p[i].getExpression());
		}
		return sb.toString();
	}
	
	public String getGroup() {
		if (atom) return expression;
		else return "(?:"+expression+')';
	}
	
	public static String getGroup (Rex... p) {
		if (p==null) return "";
		if (p.length == 0) return "";
		if (p.length == 1) return p[0].getGroup();
		StringBuffer sb = new StringBuffer();
		sb.append("(?:");
		for (int i = 0; i < p.length; i++) {
			sb.append(p[i].getExpression());
		}
		sb.append(')');
		return sb.toString();
		
	}

	public static String encode (char ch) {
		String tmpBuf;
		if( ch == '\\' )
		{
			tmpBuf = "\\\\";
		}
		else if( ch == '\"' )
		{
			tmpBuf = "\\\"";
		}
		else if( ch == '/' )
		{
			tmpBuf = "\\/";
		}
		else if( ch == '\t' )
		{
			tmpBuf = "\\t";
		}
		else if( ch == '\f' )
		{
			tmpBuf = "\\f";
		}
		else if( ch == '\r' )
		{
			tmpBuf = "\\r";
		}
		else if( ch == '\n' )
		{
			tmpBuf = "\\n";
		}
		else if( ch < ' ' ) // \xFF does not exist in JSON and \' neither !!!
		{
			tmpBuf = "\\x" + Integer.toHexString(ch+0x100).substring(1).toUpperCase();
		}
		else if( ch > '~' )
		{
			tmpBuf = "\\u" + Integer.toHexString(ch+0x10000).substring(1).toUpperCase();
		}
		else if ("!\"#$%&'()*+,-./:;<=>?@[\\]^`{|}~".indexOf(ch) >= 0)
		{
			tmpBuf =  "\\"+ch ;
		}
		else
		{
			tmpBuf =  ""+ch ; // letters,digits, _ or space
		}
		return tmpBuf;
	}
}
